/*
   Copyright 2009 Bégaudeau Stéphane

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */

package faneclipse.views;

import faneclipse.editors.FanEditor;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.viewers.TreeViewer;

import org.eclipse.swt.widgets.Composite;

import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.views.contentoutline.ContentOutlinePage;

/**
 * @author BEGAUDEAU stephane
 */
public class FanContentOutlinePage extends ContentOutlinePage {
	/**
	 * The Fan Editor.
	 */
	private FanEditor fanEditor;
	
	/**
	 * the editor input.
	 */
	private IEditorInput editorInput;
	
	/**
	 * the treeviwer.
	 */
	private TreeViewer viewer;
	
	/**
	 * the root of our tree.
	 */
	private TreeParent invisibleRoot;
	
	/**
	 * The constructor.
	 * @param fanEditor The Fan Editor.
	 */
	public FanContentOutlinePage(final FanEditor fanEditor) {
		this.fanEditor = fanEditor;
	}
	
	/**
	 * @param parent The composite.
	 * @see org.eclipse.ui.views.contentoutline.ContentOutlinePage#createControl(org.eclipse.swt.widgets.Composite)
	 */
	public final void createControl(final Composite parent) {
		super.createControl(parent);
		viewer = this.getTreeViewer();
		viewer.setContentProvider(new FanContentProvider(this));
		viewer.setLabelProvider(new FanLabelProvider());
		viewer.addSelectionChangedListener(this);
		
		if (editorInput != null)
		{
			viewer.setInput(editorInput);
		}
		viewer.expandAll();
	}

	/**
	 * @return the editor input.
	 */
	public final IEditorInput getEditorInput() {
		return editorInput;
	}

	/**
	 * @param editorInput The new editor input.
	 */
	public final void setInput(final IEditorInput editorInput) {
		this.editorInput = editorInput;
	}
	
	/**
	 * @return The invisibleRoot.
	 */
	public final TreeParent getInvisibleRoot() {
		return invisibleRoot;
	}

	/**
	 * @param invisibleRoot the new invisibleRoot.
	 */
	public final void setInvisibleRoot(final TreeParent invisibleRoot) {
		this.invisibleRoot = invisibleRoot;
	}
	
	/**
	 * @see org.eclipse.ui.views.contentoutline.ContentOutlinePage#setFocus()
	 */
	@Override
	public final void setFocus() {
		viewer.getControl().setFocus();
	}
	
	/**
	 * Initialize the tree.
	 */
	public final void initialize() {
		//FIXME Refactoring !!
		IDocumentProvider provider = fanEditor.getDocumentProvider();
		IDocument document  = null;
		if(provider != null && editorInput != null)
		{
			document = provider.getDocument(editorInput);
		}
		invisibleRoot = new TreeParent("root");
		TreeParent classParent = new TreeParent("class");
		Pattern classPattern = Pattern.compile("class [A-Z][a-z]*");
		Pattern classCommentPattern = Pattern.compile("//.*class [A-Z][a-z]*");
		if(document != null)
		{
			for(int cpt = 1; cpt < document.getNumberOfLines(); cpt++)
			{
				try
				{
					int begin = document.getLineOffset(cpt);
					int length = document.getLineLength(cpt);
					String line = document.get().substring(begin, begin+length).trim();
					Matcher classMatch = classPattern.matcher(line);
					Matcher classCommentMatch = classCommentPattern.matcher(line);
					if(classMatch.find() && !classCommentMatch.find())
					{
						String className = line.substring(classMatch.start(), classMatch.end());
						className = className.substring(6);
						TreeObject classTree = new TreeObject(className);
						classParent.addChild(classTree);
					}
				}
				catch (BadLocationException e)
				{
					e.printStackTrace();
				}
			}
		}
		invisibleRoot.addChild(classParent);
	}
}
